package com.genia.toolbox.projects.csv.business.manager.impl;

import java.util.Map;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.el.VariableMapper;

import de.odysseus.el.ExpressionFactoryImpl;
import de.odysseus.el.util.SimpleContext;

/**
 * the {@link VariableResolver} that allows us to parse EL expression.
 */
public class CsvVariableResolver
    extends SimpleContext
{

  /**
   * the {@link ExpressionFactory} to parse EL.
   */
  public static final ExpressionFactory EXPRESSION_FACTORY = new ExpressionFactoryImpl();

  /**
   * the {@link VariableMapper} to use.
   */
  private class CsvVariableMapper
      extends VariableMapper
  {

    /**
     * resolve a variable given its name.
     * 
     * @param variable
     *          The variable name
     * @return the ValueExpression assigned to the variable, null if there is no
     *         previous assignment to this variable.
     * @see javax.el.VariableMapper#resolveVariable(java.lang.String)
     */
    @Override
    public ValueExpression resolveVariable(String variable)
    {
      if (entitiesValues.containsKey(variable)) {
        return EXPRESSION_FACTORY.createValueExpression(getEntitiesValues().get(variable), Object.class);
      }
      if (fieldsValues.containsKey(variable)) {
        return EXPRESSION_FACTORY.createValueExpression(getFieldsValues().get(variable), Object.class);
      }
      return null;
    }



    /**
     * Assign a ValueExpression to an EL variable, replacing any previously
     * assignment to the same variable. The assignment for the variable is
     * removed if the expression is <code>null</code>.
     * 
     * @param variable
     *          The variable name
     * @param expression
     *          The ValueExpression to be assigned to the variable.
     * @return The previous ValueExpression assigned to this variable, null if
     *         there is no previouse assignment to this variable.
     * @see javax.el.VariableMapper#setVariable(java.lang.String,
     *      javax.el.ValueExpression)
     */
    @Override
    public ValueExpression setVariable(String variable, ValueExpression expression)
    {
      assert (false);
      return null;
    }

  }

  /**
   * the {@link VariableMapper} to use.
   */
  private CsvVariableMapper cvsVariableMapper = new CsvVariableMapper();



  /**
   * Retrieves the <code>VariableMapper</code> associated with this
   * <code>ELContext</code>.
   * 
   * @return The variable mapper to be consulted for the resolution of EL
   *         variables.
   * @see javax.el.ELContext#getVariableMapper()
   */
  @Override
  public VariableMapper getVariableMapper()
  {
    return cvsVariableMapper;
  }

  /**
   * the current values of the entities.
   */
  private Map<String, Object> entitiesValues;

  /**
   * the values of the field of the csv.
   */
  private Map<String, Object> fieldsValues;



  /**
   * getter for the entitiesValues property.
   * 
   * @return the entitiesValues
   */
  public Map<String, Object> getEntitiesValues()
  {
    return entitiesValues;
  }



  /**
   * getter for the fieldsValues property.
   * 
   * @return the fieldsValues
   */
  public Map<String, Object> getFieldsValues()
  {
    return fieldsValues;
  }



  /**
   * setter for the entitiesValues property.
   * 
   * @param entitiesValues
   *          the entitiesValues to set
   */
  public void setEntitiesValues(Map<String, Object> entitiesValues)
  {
    this.entitiesValues = entitiesValues;
  }



  /**
   * setter for the fieldsValues property.
   * 
   * @param fieldsValues
   *          the fieldsValues to set
   */
  public void setFieldsValues(Map<String, Object> fieldsValues)
  {
    this.fieldsValues = fieldsValues;
  }

}